UDP Server
该驱动内置了一个 udp server 服务, 驱动启动后可以接收客户端发送的数据. 如果使用容器部署时, 需要将 udp 服务端口开放.
配置说明
以下内容为 udp-server
驱动的配置项
server:
port: 9606 # UDP 监听的端口, 默认 9606
脚本说明
脚本语言: JavasScript ECMAScript 5.1
驱动使用时要求提供 数据处理脚本
来处理接收和发送数据过程中的协议和数据格式问题.
在脚本的上下文中内置了 Buffer
包, 可用于处理接收或发送二进制数据.
除此之外, 还内置了 lodash
, crypto-js
, moment
, xml-js
和 formulajs(Excel函数)
包.
注: 所有的脚本函数名必须为
handler
客户端对象
客户端对象, 可以获取当前数据包的来源信息(包括: IP和Port). 并且可以管理数据上下文对象.
remoteAddr(属性)
用于获取发送数据包的客户端信息. 例如: 192.168.100.123:53041
示例
/**
* 连接处理脚本, 当与服务端连接建立或断开时执行的操作
*
* @param {object} client 客户端对象
* @param {Buffer} data 接收到的数据包
*/
function handler(client, data) {
// 例如: 192.168.100.123:53041
const remoteAddr = client.remoteAddr;
}
ip(属性)
用于获取发送数据包的客户端的IP地址. 例如: 192.168.100.123
示例
/**
* 连接处理脚本, 当与服务端连接建立或断开时执行的操作
*
* @param {object} client 客户端对象
* @param {Buffer} data 接收到的数据包
*/
function handler(client, data) {
// 例如: 192.168.100.123
const ipAddr = client.ip;
}
port(属性)
用于获取发送数据包的客户端的端口. 例如: 53041
示例
/**
* 连接处理脚本, 当与服务端连接建立或断开时执行的操作
*
* @param {object} client 客户端对象
* @param {Buffer} data 接收到的数据包
*/
function handler(client, data) {
// 例如: 53041
const port = client.port;
}
getContext
用于获取数据上下文对象, 可以在数据上下文中存储数据. 数据上下文对象
注: 第一次调用的时候才会创建数据上下文
参数说明
参数名 | 参数类型 | 参数说明 | 示例值 |
---|---|---|---|
contextId | String | 上下文标识 | "myContext" |
返回值
Object
. 数据上下文对象
示例
function handler(client, data) {
// 获取一个标识为 myContext 的上下文
var myContext = client.getContext("myContext");
// 使用客户端 IP 地址作为标识
var context = client.getContext(client.getRemoteIp());
}
getDeviceContext
用于获取设备数据上下文对象, 使用设备标识作为上下文标识, 可以在上下文中存储数据. 数据上下文对象
与 getContext
不同的是, 当设备被删除后, 重启驱动时会自动清理被删除设备的上下文对象.
注: 第一次调用的时候才会创建数据上下文
参数说明
参数名 | 参数类型 | 参数说明 | 示例值 |
---|---|---|---|
deviceId | String | 设备标识 | "ST10001" |
返回值
Object
. 数据上下文对象
示例
function handler(client) {
// 获取设备 ST10001 的上下文
var context = client.getDeviceContext("ST10001");
}
removeContext
删除上下文对象
参数说明
参数名 | 参数类型 | 参数说明 | 示例值 |
---|---|---|---|
contextId | String | 上下文标识 | "myContext" |
返回值
无
示例
function handler(client) {
// 删除标识为 myContext 的上下文
client.removeContext("myContext");
// 删除以客户端 IP 地址作为标识的上下文
client.removeContext(client.getRemoteIp());
}
removeDeviceContext
删除设备上下文对象
参数说明
参数名 | 参数类型 | 参数说明 | 示例值 |
---|---|---|---|
deviceId | String | 上下文标识 | "ST10001" |
返回值
无
示例
function handler(client) {
// 删除设备 ST10001 的上下文
client.removeDeviceContext("ST10001");
}
getContextIds
获取全部上下文标识(不包含设备上下文)
参数说明
无
返回值
String[]
示例
function handler(client) {
// 创建两个上下文
const context1 = client.getContext("context1");
const context2 = client.getContext("context2");
// 获取全部上下文标识 ["context1", "context2"]
const contextIds = client.getContextIds();
}
getDeviceContextIds
获取全部设备上下文标识(只包含设备上下文)
参数说明
无
返回值
String[]
示例
function handler(client) {
// 创建两个设备上下文
const context1 = client.getDeviceContext("ST10001");
const context2 = client.getDeviceContext("ST10002");
// 获取全部设备上下文标识 ["ST10001", "ST10002"]
const contextIds = client.getDeviceContextIds();
}
数据上下文
数据上下文对象, 用来存储数据.
注: 可以根据需求创建多个上下文对象, 但是上下文对象以及上下文中的数据需要及时清理, 否则会造成
OOM
问题, 导致驱动程序崩溃.
put
用于向上下文中存储数据.
注: 存入的数据需要自行清理, 否则可能导致
OOM
等问题.
参数说明
参数名 | 参数类型 | 参数说明 |
---|---|---|
key | string | 数据项的 key |
value | any | 数据项的值 |
返回值
无
示例
function handler(client, request) {
// 获取或创建标识为 myContext 的上下文
const context = client.getContext("myContext");
// 向上下文中存储一个字符串
context.put("string", "this is a string");
// 向上下文中存储一个数值
context.put("number", 3.141);
// 向上下文中存储一个对象
context.put("object", {name: "张三", age: 18});
// 获取或创建设备 ST10001 的上下文
const deviceContext = client.getDeviceContext("ST10001");
// 向上下文中存储一个字符串
deviceContext.put("string", "this is a string");
// 向上下文中存储一个数值
deviceContext.put("number", 3.141);
// 向上下文中存储一个对象
deviceContext.put("object", {name: "张三", age: 18});
}
containsKey
判断上下文中是否存在指定的 key
参数说明
参数名 | 参数类型 | 参数说明 |
---|---|---|
key | string | 数据项的 key |
返回值
bool
. true
表示 key
存在, false
表示 key
不存在
示例
function handler(client) {
// 获取标识为 myContext 的上下文
const context = client.getContext("myContext");
// 向上下文中存储一个字符串
context.put("string", "this is a string");
// 返回 true
context.containsKey("string");
// 返回 false
context.containsKey("string1");
}
get
从上下文中获取指定的 key
对应的数据. 如果 key
不存在则返回 undefined
参数说明
参数名 | 参数类型 | 参数说明 |
---|---|---|
key | string | 数据项的 key |
返回值
any
或 undefined
. 返回 put
时写入的数据.
示例
function handler(client) {
// 获取标识为 myContext 的上下文
const context = client.getContext("myContext");
// 向上下文中存储一个字符串
context.put("string", "this is a string");
// 返回 "this is a string"
context.get("string");
// 返回 undefined
context.get("string1");
}
getAndRemove
从上下文中获取指定的 key
对应的数据并且在返回后 删除 该 key
. 如果 key
不存在则返回 undefined
.
注: 该函数返回后, 再使用
get
或getAndRemove
均返回undefined
.
参数说明
参数名 | 参数类型 | 参数说明 |
---|---|---|
key | string | 数据项的 key |
返回值
any
或 undefined
. 返回 put
时写入的数据.
示例
function handler(client) {
// 获取标识为 myContext 的上下文
const context = client.getContext("myContext");
// 向上下文中存储一个字符串
context.put("string", "this is a string");
// 返回 "this is a string"
context.getAndRemove("string");
// 返回 undefined
context.get("string");
// 返回 undefined
context.getAndRemove("string");
}
remove
从上下文中删除指定的 key
, 如果 key
不存在则不执行任何操作.
参数说明
参数名 | 参数类型 | 参数说明 |
---|---|---|
key | string | 数据项的 key |
返回值
无
示例
function handler(client) {
// 获取标识为 myContext 的上下文
const context = client.getContext("myContext");
// 向上下文中存储一个字符串
context.put("string", "this is a string");
// 数据被删除
context.remove("string");
// 不执行任何操作
context.remove("string");
}
数据处理脚本
该脚本用于处理接收到的数据包, 根据协议和数据格式将数据包解析为平台定义的数据格式.
函数定义如下:
/**
* 数据处理脚本, 解析从客户端接收到的数据并转换为平台规定的数据格式
*
* @param {object} context 上下文对象
* @param {Buffer} buffer 接收到的数据包
* @return {Array} 解析出的采集数据信息
*/
function handler(context, buffer) {
// 数据包处理逻辑
// 返回结果必须为数组, 数组中每个元素为一个设备的实时数据信息
return [
{
"id": "d01", // 设备标识
"time": 1665999863637, // 数据采集时间(ms), unix 时间戳
"values": {"key1": "str", "key2": 123} // 数据点, key 为数据点的标识, value: 为数据点的值
}
];
}
参数说明
参数名 | 参数类型 | 参数说明 |
---|---|---|
context | object | 上下文对象 |
buffer | Buffer | 客户端发送的数据包 |
返回值
参数名 | 参数类型 | 参数说明 | 示例值 |
---|---|---|---|
array[object] | 对象数组 | 返回值 | [{"id":"d01","time":1665999863637,"values":{"temperature":17.5,"humidity":35.7}}] |
id | 字符串 | 资产编号或设备标识 | d01 |
time | 数值 | 时间戳(ms) | 1664256913000 |
fields | 对象 | 数据点信息 | {"temperature":17.5,"humidity":35.7} |
key | 字符串 | 数据点标识 | "temperature" |
value | any | 数据点的值 | 17.5 |
示例
function handler(target, buffer) {
// 以 json 格式为例, 例如: {"id":"d01","time":"2022-10-17 17:57:32","values":[{"name":"temperature","data":17.5},{"name":"humidity","data":35.7}]}
const jsonData = JSON.parse(buffer.toString());
const time = moment(jsonData.time, "YYYY-MM-DD HH:mm:ss");
const values = {};
for (let i = 0; i < jsonData.values.length; i++) {
const value = jsonData.values[i];
values[value.name] = value.data;
}
return [
{id: jsonData.id, values: values, time: time.valueOf()}
]
}